package org.tigr.htc.request;

/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.tigr.antware.shared.command.events.CommandRuntimeStatusLI;
import org.tigr.antware.shared.command.events.CommandStatusLI;
import org.tigr.antware.shared.command.events.FailureEvent;
import org.tigr.antware.shared.command.events.FinishEvent;
import org.tigr.antware.shared.command.events.InterruptEvent;
import org.tigr.antware.shared.command.events.ResumeEvent;
import org.tigr.antware.shared.command.events.StartEvent;
import org.tigr.antware.shared.command.events.SubmitEvent;
import org.tigr.antware.shared.command.events.SuspendEvent;
import org.tigr.htc.cmd.Command;
import org.tigr.htc.cmd.TaskGroup;

/**
 * The <b>MockServer</b> for testing purposes
 */

public class MockServer
	implements CommandRuntimeStatusLI, CommandStatusLI, IProxyServer {
	
	static Logger log = Logger.getLogger(MockServer.class);
	static private Runtime rt = Runtime.getRuntime();
	private HTCRequest request;
    /**
     * The variable <code>local</code> holds the local submission status of the server  
     */
    private static boolean local = true;
    
    /**
     * The variable <code>passEnvironment</code> hold the configuration value for this configuration
     */
    private boolean passEnvironment = true;
    
	public MockServer(String p_configFile) {
		// nothing
	}

	public Command getCommand(long p_id) throws IOException {
		log.warn("Mock server can't get command  ");
		throw new IOException("Mock server can't get command ");
	}

	public boolean isNFS(String p_dir) throws FileNotFoundException {
		File testFile = new File(p_dir);
		Process p;

		log.debug("in isNFS");
		for (int i = 0; i < 2; i++) {
			if (testFile.exists()) {
				log.debug("File exists");
				try {
					log.debug(" cmd is " + p_dir);
					p = rt.exec("/bin/df -t nfs " + p_dir);
					BufferedReader out =
						new BufferedReader(new InputStreamReader(p.getInputStream()));
					String line = null;

					line = out.readLine(); // eat header
					log.debug("df out " + line);
					line = out.readLine();
					log.debug("df out " + line);
					if (line != null) {
						return true;
					}

					int exitVal = p.waitFor();
					log.debug("Process exitValue: " + exitVal);
					return false;
				} catch (Exception e) {
					log.debug("Exception " + e);
					return false;
				}
			} else {
				log.debug("file doesn't exists" + testFile.getName());
				if ((testFile = testFile.getParentFile()) != null) {
					p_dir = testFile.getAbsolutePath();
				} else {
					break;
				}
			}
		}
		throw new FileNotFoundException("Path or File doesn't exist " + p_dir);
	}

	/*
	 * take a request and submit it
	 */
	public long submit(HTCRequest p_request) throws IllegalAccessException {
		try {
			long id = p_request.cmd.getID();
			request = p_request;

			log.debug(" create generator thread \n");
			Thread t = new Thread(new Runnable() {
				public void run() {
// 				    try {
// 					//    tg.generateEvents();
// 				    } catch (Exception e) {
// 					System.out.println("error in mock server " + e.getMessage());
// 					e.printStackTrace();
// 				    }
				}
			});
			log.debug("Start generator thread \n");
			t.start();
			log.debug("Return id \n");
			return id;
		} catch (Exception e) {
			log.debug("Mock monitor error ", e);
			return new Integer(-1).longValue();
		}

	}

	public long waitForRequest(HTCRequest request)
		throws InterruptedException, IllegalAccessException {
		if ((this.request == null) || (request.cmd.getID() != this.request.cmd.getID())) {
			throw new IllegalAccessException("Not submitted yet");
		}
		return request.cmd.getID();
	}

	public long waitForRequest(HTCRequest request, long p_millis)
		throws InterruptedException, IllegalAccessException {
		if ((this.request == null) || (request.cmd.getID() != this.request.cmd.getID())) {
			throw new IllegalAccessException("Not submitted yet");
		}
		return request.cmd.getID();
	}

	// call server
	public Map getStatus(HTCRequest request) {
		return (Map) new HashMap();
	}

	public Command getCommand(long id, HTCRequest request) throws IOException {
	    throw new IOException("Mock server doesn't support action");
	}

	public void requestToMonitor(HTCRequest request) {
		this.request = request;
	}

	public void resume(HTCRequest request) throws IOException {
		throw new IOException("Mock server doesn't support action");
	}

	public void stop(HTCRequest request) throws IOException {
		throw new IOException("Mock server doesn't support action");
	}

	public void hold(HTCRequest p_request) throws IOException {
		throw new IOException("Mock server doesn't support action");
	}

	public void disconnect(HTCRequest p_request) throws IOException {
		throw new IOException("Mock server doesn't support action");
	}
    
    public String getMonitorHost(HTCRequest p_request) throws IOException {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            throw new IOException("Mock server could not release job: " + p_request.cmd);
        }
    }
    
	public TaskGroup getTasks(HTCRequest p_request) throws IOException {
		throw new IOException("Mock server doesn't support action");
	}
    
	public void commandStarted(StartEvent p_event) {
		request.cmd.fireStartEvent(p_event);
	}

	public void commandFinished(FinishEvent p_event) {
		request.cmd.fireFinishEvent(p_event);
	}

	public void commandRestarted(StartEvent p_event) {
		request.cmd.fireRestartEvent(p_event);
	}

	public void commandInterrupted(InterruptEvent p_event) {
		request.cmd.fireInterruptEvent(p_event);
	}

	public void commandFailed(FailureEvent p_event) {
		request.cmd.fireFailureEvent(p_event);
	}

	public void commandResumed(ResumeEvent p_event) {
		request.cmd.fireResumeEvent(p_event);
	}

	public void commandSuspended(SuspendEvent p_event) {
		request.cmd.fireSuspendEvent(p_event);
	}

	public void commandSubmitted(SubmitEvent p_event) {
		request.cmd.fireSubmitEvent(p_event);
	}


    /**
     * The method <code>isLocal</code> returns the status of the proxy server. For local submissions this 
     * value is true and for remote submissions the value is false.
     *  
     * @return boolean true to indicate the server is performing local submits
     */
	public boolean isLocal() {
		return local;
	}

    /**
     * The method <code>isPassEnvironment</code> provides the configuration for the proxy server
     * to pass the local environment to the grid jobs. This is read from a global configuration file.
     * 
     * @return a <code>boolean</code> of true if the environment is explicitly passed to the grid jobs
     * when the environment is not set by the user.
     */
	public boolean isPassEnvironment() {
		return passEnvironment;
	}
	
	/**
	 * run starting point
	 * 
	 * 
	 *  
	 */
	public void run() {
		try {
			// create events
		} catch (Exception e) {
			log.fatal("main -- " + e.getMessage(), e);
		}
	}

}
